<template>
  <!-- 添加和修改课时表单 -->
  <el-dialog :visible.sync="dialogVisible" :title="title" @close="close">
    <el-form
      ref="periodForm"
      :rules="periodRules"
      status-icon
      :model="period"
      label-width="120px">

      <el-form-item label="课时标题" prop="periodName">
        <el-input v-model="period.periodName" maxlength="50" show-word-limit/>
      </el-form-item>

      <el-form-item label="课时排序">
        <el-input-number v-model="period.sort" :min="0" :max="999"/>
      </el-form-item>

      <el-form-item label="是否免费">
        <el-radio-group v-model="period.free">
          <el-radio-button :label="0" v-if="isFree !== true">收费</el-radio-button>
          <el-radio-button :label="1">免费</el-radio-button>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="上传视频">
        <el-upload
          ref="upload"
          :on-change="fileChange"
          :on-exceed="handleUploadExceed"
          :on-remove="handleVodRemove"
          :before-remove="beforeVodRemove"
          :file-list="vodList"
          accept=".avi,.flv,.mp4,.rmvb,.wmv"
          :auto-upload="false"
          action=""
          :limit="1"
          class="upload-demo">
          <el-button slot="trigger" size="medium" type="primary">选取文件</el-button>
          <el-button
            :disabled="uploadDisabled"
            style="margin-left: 10px;"
            size="medium"
            type="success"
            @click="authUpload">开始上传</el-button>

          <div slot="tip" class="el-upload__tip">文件大小最大支持500M，<br>
              支持AVI、FLV、MP4、RMVB、WMV等视频格式上传，上传期间请不要关闭本页面！
          </div>
        </el-upload>

        <div>
          <span>{{ statusText }}</span>
          <el-progress v-if="authProgress"
            :text-inside="true"
            :stroke-width="15"
            :percentage=authProgress></el-progress>
        </div>
      </el-form-item>

    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="close">取 消</el-button>
      <el-button type="primary" @click="saveOrUpdate">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
  import { savePeriod,getPeriodById,updatePeriodById } from '@/api/period'
  import { deleteVideoById, getUploadAuth, refreshUploadAuth } from '@/api/vod'
  import { validNormal } from '@/utils/validate'


  export default {

    // 父组件向子组件传值
    props: {
      courseId: {
        type: String,
        default: null
      },
      isFree: {
        type: Boolean,
        default: false
      }
    },
    data() {

      //检验课时名称
      const validateName = (rule, value, callback) => {
        if (value.length < 5 || value > 50 || !validNormal(value)){
          callback(new Error("请输入正确的章节名称，长度要求为5-50，且不能输入特殊字符"))
        }
        else callback()
      }

      return {
        title: '',
        periodCategory: 0,
        dialogVisible: false,
        period: {
          periodId: '',
          courseId: '',
          chapterId: '',
          periodName: '',
          videoName: '',
          sort: 0,
          free: 0,
        },

        //检验规则
        periodRules:{
          periodName: [{trigger: 'blur',validator: validateName}]
        },

        vodList: [],  // 上传视频列表
        BASE_API: process.env.VUE_APP_BASE_API, // 接口API地址
        OSS_URL: 'http://czz-education.oss-cn-shenzhen.aliyuncs.com/', //阿里云oss地址

        //上传视频参数
        timeout: '',
        partSize: '',
        parallel: '',
        retryCount: '',
        retryDuration: '',
        region: 'cn-shanghai',
        userId: '1634605963684131',
        //上传文件
        file: null,
        //上传进度
        authProgress: null,
        uploadDisabled: true,
        //上传组件
        uploader: null,
        //上传状态
        statusText: ''
      }
    },

    methods: {
      open(chapterId, periodId) {
        this.dialogVisible = true
        this.period.chapterId = chapterId
        this.period.courseId = this.courseId
        this.period.video = 1

        if (this.isFree){
          this.period.free = 1
        }

        if (periodId){
          this.title = '修改课程视频课时'
          getPeriodById(periodId).then(result => {
            this.period = result.data.item

            delete this.period.gmtCreate
            delete this.period.gmtModified

            if (this.period.videoId && this.period.videoName) {
              this.vodList = [{ 'name': this.period.videoName }]
            }

          })
        }
        else {
          this.title = '新增课程视频课时'
        }
      },

      close() {
        this.$refs.periodForm.resetFields();
        this.dialogVisible = false
        // 重置表单
        this.resetForm()
      },

      resetForm() {
        this.period.periodName = ''
        this.period.sort = 0
        this.period.chapterId = ''
        this.period.periodId = ''
        this.period.courseId = ''
        this.period.free = 0
        this.period.videoId = ''
        this.period.videoName = ''
        this.file = null
        this.authProgress = null
        this.uploadDisabled = true
        this.uploader = null
        this.statusText = ''
        this.vodList = []
      },

      saveOrUpdate() {
        this.$refs.periodForm.validate((valid) => {
          if (valid) {
            //检验通过
            //判断是否有上传文件或者视频
            if (!this.period.videoId){
              this.$message.error("请上传课程视频！")
              return false
            }
            if (!this.period.periodId) {
              this.save()
            } else {
              this.update()
            }
          }
          else {
            return false
          }
        })
      },

      save() {
        this.period.courseId = this.courseId
        savePeriod(this.$qs.stringify(this.period)).then(result => {
          if (result.code === 20000){
            this.$message({
              type: 'success',
              message: '保存成功！'
            })
            // 关闭组件
            this.close()
            // 调用父组件监听函数
            this.$emit('onSaveSuccess')
          }
        })
      },

      update() {
        updatePeriodById(this.period.periodId, this.$qs.stringify(this.period)).then(result => {
          if (result.code === 20000){
            this.$message({
              type: 'success',
              message: '修改成功！'
            })
            // 关闭组件
            this.close()
            // 调用父组件监听函数
            this.$emit('onSaveSuccess')
          }
        })
      },

      // 文档/视频删除前回调
      beforeVodRemove(file) {
        if (file && file.status==="success") {
          return this.$confirm(`确定移除 ${file.name}？`)
        }
      },

      // 上传多个文档/视频
      handleUploadExceed(){
        this.$message.warning('想要重新上传文件，请先删除已上传的文件')
      },

      // 视频确定删除回调
      handleVodRemove(file, fileList) {
        if (file && file.status==="success") {
          deleteVideoById(this.period.videoId).then(result=>{
            if (result.code === 20000){
              this.period.videoId = ''
              this.period.videoName = ''

              if (this.period.periodId){
                // 更新课时信息
                updatePeriodById(this.period.periodId, this.$qs.stringify(this.period)).then(result => {})
                this.$message({
                  type: 'success',
                  message: result.message
                })
                // 获取最新乐观锁
                getPeriodById(this.period.periodId).then(result => {
                  this.period = result.data.item

                  delete this.period.gmtCreate
                  delete this.period.gmtModified
                })
              }

            }
          })
        }
      },

      //选取视频文件
      fileChange(file, vodList){
        this.file = file.raw
        if (!this.file) {
          alert('请先选择需要上传的视频！')
          return
        }
        //获取后缀
        const suffix = file.name.substring(file.name.lastIndexOf('.') + 1)

        const isAVI = suffix === 'avi';
        const isFLV = suffix === 'flv';
        const isMP4 = suffix === 'mp4';
        const isRMVB = suffix === 'rmvb';
        const isWMV = suffix === 'wmv';
        const isVIDEO = (isAVI || isFLV || isMP4 || isRMVB || isWMV)
        const isLt500M = file.size / 1024 / 1024 < 500;

        if (!isVIDEO) {
          this.$message.error('上传视频只能是 AVI、FLV、MP4、RMVB、WMV 格式！');
          this.vodList = []
          return isVIDEO
        }

        if (!isLt500M) {
          this.$message.error('上传视频大小不能超过 500MB！');
          this.vodList = []
          return isLt500M
        }

        let userData = '{"Vod":{}}'
        if (this.uploader) {
          this.uploader.stopUpload()
          this.authProgress = 0
          this.statusText = ''
        }
        this.uploader = this.createUploader()
        this.uploader.addFile(this.file, null, null, null, userData)
        this.uploadDisabled = false
      },

      //上传视频，携带上传凭证
      authUpload(){
        if (this.uploader !== null) {
          this.uploader.startUpload()
          this.uploadDisabled = true
        }
      },

      //创建上传组件
      createUploader(type) {
        const self = this

        /* eslint-disable no-undef */
        const uploader = new AliyunUpload.Vod({
          userId: self.userId,//阿里账号ID ，值的来源https://help.aliyun.com/knowledge_detail/37196.html
          region: self.region,//上传到点播的地域， 默认值为'cn-shanghai',//eu-central-1,ap-southeast-1
          timeout: self.timeout || 60000,//超时时间
          partSize: self.partSize || 1048576,//分片大小默认1M，不能小于100K
          parallel: self.parallel || 5,//并行上传分片个数，默认5
          retryCount: self.retryCount || 3,//网络原因失败时，重新上传次数，默认为3
          retryDuration: self.retryDuration || 2,//网络原因失败时，重新上传间隔时间，默认为2秒
          // 添加文件成功
          addFileSuccess: function(uploadInfo) {
            //console.log('添加文件成功')
            //console.log(uploadInfo)
            self.uploadDisabled = false
            self.statusText = '添加文件成功, 等待上传...'
            //console.log('addFileSuccess: ' + uploadInfo.file.name)
          },
          // 开始上传
          onUploadstarted: function(uploadInfo) {
            //console.log('开始上传')
            //console.log(uploadInfo)
            //console.log('获取上传地址和凭证')
            const fileName = uploadInfo.file.name
            const title = fileName.substring(0, fileName.lastIndexOf('.'))
            // 调用 获取视频上传地址和凭证接口
            // 调用 uploader.setUploadAuthAndAddress 方法
            getUploadAuth(title, fileName).then(result => {
              //console.log(response)
              const uploadAuth = result.data.response.uploadAuth
              const uploadAddress = result.data.response.uploadAddress
              const videoId = result.data.response.videoId
              uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
            })
            self.statusText = '文件开始上传...'
          },
          // 文件上传成功
          onUploadSucceed: function(uploadInfo) {
            //console.log('onUploadSucceed')
            //console.log(uploadInfo.file)
            self.statusText = '文件上传成功！'
            const fileName = uploadInfo.file.name
            const title = fileName.substring(0, fileName.lastIndexOf('.'))
            self.period.videoName = title
            self.period.videoId = uploadInfo.videoId
          },
          // 文件上传失败
          onUploadFailed: function(uploadInfo, code, message) {
            //console.log('onUploadFailed: file:' + uploadInfo.file.name + ',code:' + code + ', message:' + message)
            self.statusText = '文件上传失败!'
          },
          // 文件上传进度，单位：字节, 可以在这个函数中拿到上传进度并显示在页面上
          onUploadProgress: function(uploadInfo, totalSize, progress) {
            //console.log('onUploadProgress:file:' + uploadInfo.file.name + ', fileSize:' + totalSize + ', percent:' + Math.ceil(progress * 100) + '%')
            const progressPercent = Math.ceil(progress * 100)
            self.authProgress = progressPercent
            self.statusText = '文件上传中...'
          },
          // 上传凭证超时
          onUploadTokenExpired: function(uploadInfo) {
            // 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
            // 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
            // 然后调用 resumeUploadWithAuth 方法
            refreshUploadAuth(uploadInfo.videoId).then(result => {
              //console.log(response)
              const uploadAuth = result.data.response.uploadAuth
              // 上传凭证失效后恢复上传
              uploader.resumeUploadWithAuth(uploadAuth)
              //console.log('upload expired and resume upload with uploadauth ' + uploadAuth)
            })
            self.statusText = '文件上传超时...'
          },
          // 全部文件上传结束
          onUploadEnd: function(uploadInfo) {
            //console.log('onUploadEnd: uploaded all the files')
            self.statusText = '文件上传完毕！'
          }
        })
        return uploader
      }
    }

  }
</script>

<style scoped>

</style>
